/**************************************************************************************************/
/* Game.cpp                                                                               Version */
/* Author     : Ravi Kamath (ravi.kamath@yahoo.com)                                               */
/* Created    : 08-Oct-2010 01:00                                                                 */
/* Modified   : 08-Oct-2010 01:00                                                                 */
/**************************************************************************************************/
#include <Game.hpp>

namespace Olorin
{
	namespace Game
	{
		/******************************************************************************************/
		/* Constructor and Destructor                                                             */
		/******************************************************************************************/
		Game::Game()
		{
			hInstance = 0;
			hWindow = 0;
			hDeviceContext = 0;
			hGLRC = 0;
		}
		
		Game::~Game()
		{
			disableOpenGL();
			/*
			if(hWnd)
				{
				DestroyWindow(hWnd);
				hWnd = NULL;
				}
			UnregisterClass();
			hInstance = NULL;
			*/
		}
		
		void Game::init(HINSTANCE hInstance, HWND hWindow)
		{
			this->hInstance = hInstance;
			this->hWindow = hWindow;
			enableOpenGL();
			/*
			this->hInstance = hInstance;
			WNDCLASSEX wc;
			
			wc.cbSize = sizeof(WNDCLASSEX);
			wc.style = 0;
			wc.lpfnWndProc = WndProc;
			wc.cbClsExtra = 0;
			wc.cbWndExtra = 0;
			wc.hInstance = hInstance;
			wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
			wc.hCursor = LoadCursor(NULL, IDC_ARROW);
			wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
			wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
			wc.lpszClassName = className;
			wc.hIconSm = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
			if(!RegisterClassEx(&wc))
				{
				MessageBox(NULL, "Window Registration Failes", "Error", MB_OK);
				return 0;
				}
			hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, className, "Features GUI",
					WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, C_USEDEFAULT,
					800,600,NULL, NULL, hInstance, NULL);
			if(hwnd == NULL)
				{
				MessageBox(NULL, "Window Creation Failes", "Error", MB_OK);
				return 0;
				}
			ShowWindow(hWnd, 0);
			*/
		}
		
		LRESULT CALLBACK Game::StaticWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
		{
			Game *game = 0;
			if(msg == WM_NCCREATE)
			{
				game = (Game*)((LPCREATESTRUCT)lParam)->lpCreateParams;
				SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)game);
			}
			else
				game = (Game*)GetWindowLongPtr(hWnd, GWL_USERDATA);
			if(!game)
				return DefWindowProc(hWnd, msg, wParam, lParam);
			return game->WindowProc(hWnd, msg, wParam, lParam);
		}
		
		LRESULT Game::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
		{
			return DefWindowProc(hWnd, msg, wParam, lParam);
		}
		
		/******************************************************************************************/
		/* OpenGL start and stop                                                                  */
		/******************************************************************************************/
		void Game::enableOpenGL()
		{
			PIXELFORMATDESCRIPTOR pfd;
			ZeroMemory(&pfd, sizeof(pfd));
			pfd.nSize = sizeof(pfd);
			pfd.nVersion = 1;
			pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
			pfd.iPixelType = PFD_TYPE_RGBA;
			pfd.cColorBits = 24;
			pfd.cDepthBits = 16;
			pfd.iLayerType = PFD_MAIN_PLANE;
			hDeviceContext = GetDC(hWindow);
			int format = ChoosePixelFormat(hDeviceContext, &pfd);
			SetPixelFormat(hDeviceContext, format, &pfd);
			hGLRC = wglCreateContext(hDeviceContext);
			wglMakeCurrent(hDeviceContext, hGLRC);
		}
		
		void Game::disableOpenGL()
		{
			wglMakeCurrent(NULL, NULL);
			wglDeleteContext(hGLRC);
			ReleaseDC(hWindow, hDeviceContext);
		}
		
		/******************************************************************************************/
		/* Update and draw functions - these are virtual functions                                */
		/******************************************************************************************/
		void Game::update(const GameTime& gameTime)
		{
		}
		
		void Game::draw(const GameTime& gameTime)
		{
		}
		
		void Game::updateMouseMove(WPARAM wParam, LPARAM lParam)
		{
			switch(LOWORD(wParam))
			{
				case MK_LBUTTON:
					break;
				case MK_RBUTTON:
					break;
				case MK_MBUTTON:
					break;
				default:
					break;
			}
		}
		
		void Game::updateMouseWheel(WPARAM wParam, LPARAM lParam)
		{
			int delta = (short)HIWORD(wParam);
			switch(LOWORD(wParam))
			{
				case MK_LBUTTON:
					break;
				case MK_RBUTTON:
					break;
				case MK_MBUTTON:
					break;
				default:
					break;
			}
		}
		
		void Game::updateMouseClick(WPARAM wParam, LPARAM lParam)
		{
			switch(LOWORD(wParam))
			{
				case MK_LBUTTON:
					break;
				case MK_RBUTTON:
					break;
				case MK_MBUTTON:
					break;
				default:
					break;
			}
		}
		
		void Game::updateKeyDown(WPARAM wParam, LPARAM lParam)
		{
		}
		
		void Game::updateKeyUp(WPARAM wParam, LPARAM lParam)
		{
		}
		
		/******************************************************************************************/
		/* Some other standard functions                                                          */
		/******************************************************************************************/
		void Game::resize(const unsigned int& width, const unsigned int& height)
		{
			if(!height) this->height = 1;
			this->width = width;
			float aspectRatio = (float)this->width / (float)this->height;
			glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			glViewport(0,0,this->width,this->height);
			gluPerspective(45,aspectRatio,0.1,1000);
			glMatrixMode(GL_MODELVIEW);
		}
	}
}